package cherry.orange;

import java.awt.Point;
import java.io.IOException;
import java.util.ArrayList;

import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.tiled.TiledMap;
import org.w3c.dom.Document;

import Server.Ammo;
import Server.FieldPlayer;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryonet.Client;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.Listener;

import cherry.orange.entities.Entity;
import cherry.orange.entities.MyPlayerEntity;
import cherry.orange.entities.PlayerEntity;

public class Game extends BasicGame {

	public static final int TILESIZE = 32;

	private ArrayList<Entity> entities = new ArrayList<Entity>();
	private PlayerEntity myPlayer;

	private TiledMap tiledMap;
	private boolean wait;
	private String IP;
	private String Port;

	private GameContainer container;
	private Client client = new Client();

	public Game() {
		super("The game");
		new IPConnector().setVisible(true);
		wait = true;
		while (wait) {
			try {
				Thread.sleep(50);
			} catch (Exception e) {
			}
		}
		client.start();
		try {
			client.connect(500000, IP, Integer.parseInt(Port));
		} catch (NumberFormatException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		Kryo kryo = client.getKryo();
		kryo.register(Request.class);
		kryo.register(Response.class);
		/*Request request = new Request();
		request.firstConnect = true;
		request.nickname = "Bob";
		client.sendTCP(request);*/
		client.addListener(new Listener() {
			public void received(Connection connection, Object object) {
				if (object instanceof Response) {
					Response response = (Response) object;
					System.out.println(response.text);
				}
			}
		});
	}

	@Override
	public void init(GameContainer arg0) throws SlickException {
		tiledMap = new TiledMap(
				ResourceLoader.getInputStreamTo("maps/test.tmx"));
		this.myPlayer = new MyPlayerEntity();
		this.myPlayer.setX(50);
		this.myPlayer.setY(50);
	}

	@Override
	public void render(GameContainer arg0, Graphics g) throws SlickException {

		int myX = (int) myPlayer.getX();
		int myY = (int) myPlayer.getY();

		int halfW = arg0.getWidth() / 2;
		int halfH = arg0.getHeight() / 2;

		tiledMap.render(-myX + halfW, -myY + halfH);
		for (Entity entity : entities) {
			g.pushTransform();

			g.translate(entity.getX(), entity.getY());
			entity.render(arg0, this, g);

			g.popTransform();
		}

		// Render my player
		{
			g.pushTransform();

			g.translate(halfW, halfH);
			myPlayer.render(arg0, this, g);

			g.popTransform();
		}

	}

	@Override
	public void update(GameContainer arg0, int delta) throws SlickException {
		for (Entity entity : entities) {
			entity.update(arg0, this, delta);
		}

		// Update my player
		{
			myPlayer.update(arg0, this, delta);
		}
	}

	public void addEntity(Entity entity) {
		this.entities.add(entity);
	}

	public void removeEntity(Entity entity) {
		this.entities.remove(entity);
	}

	public CollisionResponse checkCollision(Entity element, float dx, float dy) {
		ArrayList<CTile> start = new ArrayList<CTile>();
		getFoundTiles(start, element.getX() + dx, element.getY() + dy);
		getFoundTiles(start, element.getX() + element.getWidth() + dx,
				element.getY() + dy);
		getFoundTiles(start, element.getX() + element.getWidth() + dx,
				element.getY() + element.getHeight() + dy);
		getFoundTiles(start, element.getX() + dx,
				element.getY() + element.getHeight() + dy);

		for (CTile cTile : start) {
			if (cTile.id == -1)
				return CollisionResponse.CollidesAll;
			String blockProperty = tiledMap.getTileProperty(cTile.id,
					"blocked", "1");
			if (blockProperty == "1")
				return CollisionResponse.CollidesAll;
		}
		return null;

	}

	private void getFoundTiles(ArrayList<CTile> start, float x, float y) {

		int tx = (int) (x / TILESIZE);
		int ty = (int) (y / TILESIZE);
		int tid = -1;

		if (tx < 0 || ty < 0) {

		} else {
			tid = tiledMap.getTileId(tx, ty, 0);

			for (int t = 0; t < start.size(); t++) {
				CTile tt = start.get(t);
				if (tt.x == tx && tt.y == ty) {
					return;
				}
			}
		}

		CTile cTile = new CTile();
		cTile.x = tx;
		cTile.y = ty;
		cTile.id = tid;

		start.add(cTile);

	}

	private class CTile {
		public int x, y, id;
	}



	public static class Request {
		public static final int COMM_DISCONNECT = -1;
		public static final int COMM_WARN = -2;
		public static final int COMM_KICK = -3;
		public static final int COMM_BAN = -4;

		public static final int COMM_RECEIVE_DATA = 0;

		public static final int COMM_CHAT = 1;
		public static final int COMM_PCHAT = 2;
		public static final int COMM_SCHAT = 3;
		public static final int COMM_NOTICE = 4;

		public String text;
		public int comm;
		public int id;
		public Point location;
		public int health;
		public double angle;
		public Ammo ammo;
		public String nickname;
		public boolean firstConnect = false;

	}

	public static class Response {
		public static final int COMM_DISCONNECT = -1;
		public static final int COMM_WARN = -2;
		public static final int COMM_KICK = -3;
		public static final int COMM_BAN = -4;

		public static final int COMM_SEND_DATA = 0;

		public static final int COMM_CHAT = 1;
		public static final int COMM_PCHAT = 2;
		public static final int COMM_SCHAT = 3;
		public static final int COMM_NOTICE = 4;

		public String text;
		public int comm;
		public int id;
		public Document mapFile;
		public String tilesLocation;
		public ArrayList<Ammo> ammo;
		public ArrayList<FieldPlayer> players;

		public Response(String text, int comm) {
			this.text = text;
			this.comm = comm; // ref.substring(0,ref.lastIndexOf("/"))
		}

		public Response(String text, int comm, ArrayList<Ammo> ammo,
				ArrayList<FieldPlayer> players) {
			this.text = text;
			this.comm = comm; // ref.substring(0,ref.lastIndexOf("/"))
			this.ammo = ammo;
			this.players = players;
		}

		public Response(String text, int comm, int id, Document mapFile,
				String tilesLocation) {
			this.text = text;
			this.comm = comm;
			this.id = id;
			this.mapFile = mapFile;
			this.tilesLocation = tilesLocation;
		}
	}
	
	public class IPConnector extends javax.swing.JFrame {

		/** Creates new form IPConnector */
		public IPConnector() {
			initComponents();
		}

		/**
		 * This method is called from within the constructor to initialize the
		 * form. WARNING: Do NOT modify this code. The content of this method is
		 * always regenerated by the Form Editor.
		 */
		@SuppressWarnings("unchecked")
		// <editor-fold defaultstate="collapsed" desc="Generated Code">
		private void initComponents() {

			jLabel1 = new javax.swing.JLabel();
			jTextField1 = new javax.swing.JTextField();
			jButton1 = new javax.swing.JButton();
			jLabel2 = new javax.swing.JLabel();
			jTextField2 = new javax.swing.JTextField();
			jButton2 = new javax.swing.JButton();

			setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
			setTitle("Server Connector");

			jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
			jLabel1.setText("Server:");

			jButton1.setText("Cancel");
			jButton1.addActionListener(new java.awt.event.ActionListener() {

				public void actionPerformed(java.awt.event.ActionEvent evt) {
					jButton1ActionPerformed(evt);
				}
			});

			setResizable(false);

			jTextField1.setText("5.219.159.58");
			jTextField2.setText("32847");

			jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
			jLabel2.setText("Port:");

			jButton2.setText("Connect");
			jButton2.addActionListener(new java.awt.event.ActionListener() {

				public void actionPerformed(java.awt.event.ActionEvent evt) {
					jButton2ActionPerformed(evt);
				}
			});

			javax.swing.GroupLayout layout = new javax.swing.GroupLayout(
					getContentPane());
			getContentPane().setLayout(layout);
			layout.setHorizontalGroup(layout
					.createParallelGroup(
							javax.swing.GroupLayout.Alignment.LEADING)
					.addGroup(
							layout.createSequentialGroup()
									.addContainerGap()
									.addGroup(
											layout.createParallelGroup(
													javax.swing.GroupLayout.Alignment.LEADING,
													false)
													.addGroup(
															layout.createSequentialGroup()
																	.addComponent(
																			jLabel1,
																			javax.swing.GroupLayout.PREFERRED_SIZE,
																			56,
																			javax.swing.GroupLayout.PREFERRED_SIZE)
																	.addPreferredGap(
																			javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																	.addComponent(
																			jTextField1,
																			javax.swing.GroupLayout.PREFERRED_SIZE,
																			177,
																			javax.swing.GroupLayout.PREFERRED_SIZE))
													.addGroup(
															javax.swing.GroupLayout.Alignment.TRAILING,
															layout.createSequentialGroup()
																	.addGap(5,
																			5,
																			5)
																	.addComponent(
																			jButton1,
																			javax.swing.GroupLayout.DEFAULT_SIZE,
																			javax.swing.GroupLayout.DEFAULT_SIZE,
																			Short.MAX_VALUE)
																	.addPreferredGap(
																			javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																	.addComponent(
																			jButton2,
																			javax.swing.GroupLayout.DEFAULT_SIZE,
																			113,
																			Short.MAX_VALUE))
													.addGroup(
															layout.createSequentialGroup()
																	.addComponent(
																			jLabel2,
																			javax.swing.GroupLayout.PREFERRED_SIZE,
																			56,
																			javax.swing.GroupLayout.PREFERRED_SIZE)
																	.addPreferredGap(
																			javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																	.addComponent(
																			jTextField2,
																			javax.swing.GroupLayout.PREFERRED_SIZE,
																			177,
																			javax.swing.GroupLayout.PREFERRED_SIZE)))
									.addContainerGap(
											javax.swing.GroupLayout.DEFAULT_SIZE,
											Short.MAX_VALUE)));
			layout.setVerticalGroup(layout
					.createParallelGroup(
							javax.swing.GroupLayout.Alignment.LEADING)
					.addGroup(
							layout.createSequentialGroup()
									.addContainerGap()
									.addGroup(
											layout.createParallelGroup(
													javax.swing.GroupLayout.Alignment.BASELINE)
													.addComponent(jLabel1)
													.addComponent(
															jTextField1,
															javax.swing.GroupLayout.PREFERRED_SIZE,
															javax.swing.GroupLayout.DEFAULT_SIZE,
															javax.swing.GroupLayout.PREFERRED_SIZE))
									.addPreferredGap(
											javax.swing.LayoutStyle.ComponentPlacement.RELATED)
									.addGroup(
											layout.createParallelGroup(
													javax.swing.GroupLayout.Alignment.BASELINE)
													.addComponent(jLabel2)
													.addComponent(
															jTextField2,
															javax.swing.GroupLayout.PREFERRED_SIZE,
															javax.swing.GroupLayout.DEFAULT_SIZE,
															javax.swing.GroupLayout.PREFERRED_SIZE))
									.addGap(15, 15, 15)
									.addGroup(
											layout.createParallelGroup(
													javax.swing.GroupLayout.Alignment.BASELINE)
													.addComponent(
															jButton2,
															javax.swing.GroupLayout.PREFERRED_SIZE,
															23,
															javax.swing.GroupLayout.PREFERRED_SIZE)
													.addComponent(
															jButton1,
															javax.swing.GroupLayout.PREFERRED_SIZE,
															23,
															javax.swing.GroupLayout.PREFERRED_SIZE))
									.addContainerGap(
											javax.swing.GroupLayout.DEFAULT_SIZE,
											Short.MAX_VALUE)));

			pack();
		}// </editor-fold>

		private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
			IP = jTextField1.getText();
			Port = jTextField2.getText();
			wait = false;
			dispose();
		}

		private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
			wait = true;
			dispose();
		}

		/**
		 * @param args
		 *            the command line arguments
		 */
		// Variables declaration - do not modify
		private javax.swing.JButton jButton1;
		private javax.swing.JButton jButton2;
		private javax.swing.JLabel jLabel1;
		private javax.swing.JLabel jLabel2;
		private javax.swing.JTextField jTextField1;
		private javax.swing.JTextField jTextField2;
		// End of variables declaration
	}

}
